﻿/******************************************************************************
 * 【本类功能概述】                                 					      *
 *  版权所有（C）2017-                                           *
 *  保留所有权利。                                                            *
 ******************************************************************************
 *  作者 : <hughjk>
 *  创建时间:2020年3月2日 14:11:51
 *  文件描述:编辑器工具类
 *****************************************************************************/

using System;
using System.Collections.Generic;

namespace UtilEditors
{
    public class TimerEditor
    {
        private static TimerEditor instance;
        public static TimerEditor Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new TimerEditor();
                }
                return instance;
            }
        }

        public class TimerProc
        {
            public float duration;
            public float time;
            public int loop = -1;
            public Action Call = delegate { };
            DateTime ct;
            internal bool run;

            public TimerProc()
            {
                run = true;
                ct = DateTime.Now;
            }

            public void SubTime()
            {
                time = duration - (float)DateTime.Now.Subtract(ct).TotalSeconds;
                if (time <= 0)
                {
                    run = false;
                }
            }
            public void Reset()
            {
                ct = DateTime.Now;
                time = duration;
            }
        }

        private List<TimerProc> list = null;
        private List<TimerProc> addList = null;
        private List<TimerProc> removeList = null;


        public TimerEditor()
        {
            list = new List<TimerProc>();
            addList = new List<TimerProc>();
            removeList = new List<TimerProc>();
        }

        public void Dispose()
        {
            instance = null;
            list.Clear();
            addList.Clear();
            removeList.Clear();
        }

        public TimerProc Add(float duration, int loop, Action call)
        {
            TimerProc proc = new TimerProc();
            proc.duration = duration;
            proc.time = duration;
            proc.loop = loop;
            proc.Call = call;
            addList.Add(proc);
            return proc;
        }
        public TimerProc Add(float duration, Action call)
        {
            return Add(duration, 0, call);
        }
        /// <summary>
        /// 添加一个重置计时器,如果这个计时器存在则重置,如果不存在就 是一个新的
        /// </summary>
        /// <param name="duration"></param>
        /// <param name="tp"></param>
        /// <param name="call"></param>
        public void Add(float duration, ref TimerProc tp, Action call)
        {
            if (tp != null && tp.run)
            {
                tp.Reset();
            }
            else
            {
                tp = Add(duration, 0, call);
            }
        }

        public void Remove(object proc)
        {
            if (proc == null)
            {
                return;
            }
            TimerProc tp = proc as TimerProc;
            removeList.Add(tp);
        }

        public void Update()
        {
            DelayAddTimer();
            DelayRemoveTimer();

            for (int i = list.Count - 1; i >= 0; i--)
            {
                TimerProc proc = list[i];
                proc.SubTime();
                if (proc.time <= 0)
                {
                    try
                    {
                        proc.Call();
                    }
                    catch (Exception e)
                    {
                        list.RemoveAt(i);
                        debug.log(e);
                        continue;
                    }

                    if (proc.loop > 0)
                    {
                        --proc.loop;
                        proc.time += proc.duration;
                    }

                    if (proc.loop == 0)
                    {
                        list.RemoveAt(i);
                    }
                    else if (proc.loop < 0)
                    {
                        proc.time += proc.duration;
                    }
                }
            }
        }

        private void DelayAddTimer()
        {
            if (addList.Count > 0)
            {
                list.AddRange(addList);
                addList.Clear();
            }
        }

        private void DelayRemoveTimer()
        {
            if (removeList.Count == 0)
            {
                return;
            }

            for (int i = 0; i < removeList.Count; i++)
            {
                list.Remove(removeList[i]);
            }

            removeList.Clear();
        }
    }
}
